package luj.tool.jnproxyan.framework.proxy.actor.tell;

import luj.bean.api.BeanContext;
import luj.bean.api.bean.Bean;
import luj.cluster.api.actor.Tellable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.function.BiFunction;
import java.util.function.Supplier;

@Component
public class ActorTeller {

  public interface MBean {

    /**
     * short for field
     */
    <F> Field<F> f(Supplier<F> f);
  }

  public interface Field<F> {

    MBean set(F val);
  }

  public ActorTeller inject(Tellable actorRef) {
    var result = new ActorTeller();
    result._actorRef = actorRef;
    result._lujbean = _lujbean;
    return result;
  }

  public <M> void tell(Class<M> type, BiFunction<MBean, M, MBean> msg) {
    Bean<M> result = _lujbean.createBean(type);

    var setter = new MBeanImpl<>();
    setter._bean = result;
    msg.apply(setter, result.getSetterInstance());

    _actorRef.tell(result.getValueInstance());
  }

  Tellable _actorRef;

  @Autowired
  BeanContext _lujbean;
}
